//
//  HMNetworkTools.swift
//  Swif课堂练习第三天 下午--AFN封装网络方法
//
//  Created by wulei on 15/12/8.
//  Copyright © 2015年 wulei. All rights reserved.
//

import UIKit
import AFNetworking

enum HMRequestMethod: String{
    case GET = "GET"
    case POST = "POST"
}

// MARK: 网络工具
class HMNetworkTools: AFHTTPSessionManager {
    
    // MARK: 应用程序信息
   private let appKey = "4187896948"
   private let appSecret = "a5af07880752a270a649cc845fc6efb8"
   private let redirectUrl = "http://www.baidu.com"
    
    // 网络请求完成后 回调,类似于OC 中的typedefine
    typealias HMRequestCallBack = (result: AnyObject?, error: NSError?) -> ()
    
    
// 单例
    static let sharedTools:HMNetworkTools = {
        
        let tools = HMNetworkTools(baseURL: nil)
        
        tools.responseSerializer.acceptableContentTypes?.insert("text/plain")
        return tools
        
        
    }()
    
    // 定义一个重要的 access_token字典
    private var tokenDict: [String: AnyObject]? {
        if let token = HMUserAccountViewModel.sharedUserAccountViewModel.accessToken {
            return ["access_token": token]
        }
        
        return nil
    }
}

// MARK: - 发布微博
extension HMNetworkTools {
    /// 发布微博
    /// - parameter status:
    /// - parameter finish:
    /// - see: [http://open.weibo.com/wiki/2/statuses/update](http://open.weibo.com/wiki/2/statuses/update)
    /// - see: [https://upload.api.weibo.com/2/statuses/upload.json](https://upload.api.weibo.com/2/statuses/upload.json)
    func sendStatus(status: String, image: UIImage?, finish: HMRequestCallBack) {
        
        // 创建参数字典
       var params = [String: AnyObject]()
        // 设置参数
        params["status"] = status
        
        
        // 判断是否上传图片
        if image == nil {
            
            let URL = "https://api.weibo.com/2/statuses/update.json"
            tokenRequest(.POST, URLString: URL, parameters: params, finished: finish)
        }else {
            let URL = "https://upload.api.weibo.com/2/statuses/upload.json"
            let data = UIImagePNGRepresentation(image!)
            upload(URL, data: data!, name: "pic", parameters: params, finished: finish)
        }
        

    }
}



// MARK: - 加载微博数据
extension HMNetworkTools {

//    since_id: 若指定此参数，则返回ID比since_id大的微博（即比since_id时间晚的微博），默认为0。
//    max_id:   若指定此参数，则返回ID小于或等于max_id的微博，默认为0。
    
/// -see: [https://api.weibo.com/2/statuses/home_timeline.json](https://api.weibo.com/2/statuses/home_timeline.json)
    func loadStatus(since_id since_id: Int, max_id: Int,finish: HMRequestCallBack) {

        // 创建参数字典
        var params = [String: AnyObject]()
        
        // 判断是否下拉
        if since_id > 0 {
            
            params["since_id"] = since_id
            
        } else if max_id > 0{
            // 上拉参数
            // TODO: 上拉参数有问题,稍后演示
            params["max_id"] = max_id - 1
            
        }
    
    let URL = "https://api.weibo.com/2/statuses/home_timeline.json"

        tokenRequest(.GET, URLString: URL, parameters: params, finished: finish)

    }
}



// MARK: - 用户相关方法
extension HMNetworkTools {
    
    /// 加载用户信息 "GET"
    /// - parameter accessToken: accessToken
    /// - parameter uid:         uid
    /// - parameter finish:      完成回调
    /// - see: [http://open.weibo.com/wiki/2/users/show](http://open.weibo.com/wiki/2/users/show)
    
    func loadUserInfo(uid: String, finish: HMRequestCallBack) {

        // 创建参数字典
        var params = [String: AnyObject]()
        
        let URL = "https://api.weibo.com/2/users/show.json"
        params["uid"] = uid
        
        tokenRequest(.GET, URLString: URL, parameters: params, finished: finish)
        
    }
}


// MARK: - OAuth 相关方法
extension HMNetworkTools {
    ///  OAuth 授权 URL
    /// - see: [http://open.weibo.com/wiki/Oauth2/authorize](http://open.weibo.com/wiki/Oauth2/authorize)
    var oauthURL: NSURL{
        let urlString = "https://api.weibo.com/oauth2/authorize?client_id=\(appKey)&redirect_uri=\(redirectUrl)"
        
        return NSURL(string: urlString)!
    }
    
    
    
    // 加载 Access Token
    func loadAccessToken(code: String,finish: HMRequestCallBack) {
        
        let postURL = "https://api.weibo.com/oauth2/access_token"
        let parame = [
            "client_id": appKey,
            "client_secret": appSecret,
            "grant_type": "authorization_code",
            "code": code,
            "redirect_uri": redirectUrl
        ]
        
        request(HMRequestMethod.POST, URLString: postURL, parameters: parame, finished: finish)
        
        }
}

// MARK: AFN封装
extension HMNetworkTools {
    /// 向 parameters 字典中追加参数据
    /// - parameter parameters: 参数字典
    /// - returns: 成功 / 失败
    
    private func appendToken(inout parameters: [String: AnyObject]?) -> Bool {
        guard let token = HMUserAccountViewModel.sharedUserAccountViewModel.accessToken else {
            return false
        }
        
        if parameters == nil {
            parameters = [String: AnyObject]()
        }
        
        parameters!["access_token"] = token
        
        return true
        
    }
    
    
    /// 使用 token 进行网络请求
    /// - parameter method:     GET / POST
    /// - parameter URLString:  URLString
    /// - parameter parameters: 参数字典
    /// - parameter finished:   完成回调
    private func tokenRequest(method: HMRequestMethod, URLString:String, var parameters: [String:AnyObject]?,finished: HMRequestCallBack) {
        
      
        if !appendToken(&parameters) {
            finished(result: nil, error: NSError(domain: "cn.itcast.error", code: -1001, userInfo: ["message": ["token 为空"]]))
            return
        }
        
       
        
        request(method, URLString: URLString, parameters: parameters, finished: finished)
        
    }
    
    /// 上传文件
    /// - parameter URLString:  URLString
    /// - parameter data:       要上传文件的二进制数据
    /// - parameter name:       服务器定义的字段名称-- 后台接口文档会显示
    /// - parameter parameters: 参数字典
    /// - parameter finished:   完成回调
    private func upload(URLString: String, data: NSData, name: String, var parameters: [String: AnyObject]?, finished: HMRequestCallBack) {
        
        if !appendToken(&parameters) {
            finished(result: nil, error: NSError(domain: "cn.itcast.error", code: -1001, userInfo: ["message": ["token 为空"]]))
            return
        }
        
        // 多部分表单数据
//        var formData: AFMultipartFormData
        
        
        POST(URLString, parameters: parameters, constructingBodyWithBlock: { (formData) -> Void in
            
            // fileNmae 保存在服务器的文件名
            // 1. 可以乱写,后台会作后续处理
            // 2. 根据上传的文件生成 缩略图,中等图,高清图
            // 3. 保存不同的路径,会自动生成文件名
            
            // mimeType 客户端告诉服务器 二进制数据的准确类型
            // 不想告诉服务器准确类型 application / actet_stream 统一类型
            
            
            formData.appendPartWithFileData(data, name: name, fileName: "xxx", mimeType: "application/actet_stream")
            
            }, success: { (_, result) -> Void in
                finished(result: result, error: nil)
            }) { (_, error) -> Void in
                finished(result: nil, error: error)
        }
        
        
        
    }
    /// 网络请求
    /// - parameter method:     POST/GET
    /// - parameter URLString:  URLString
    /// - parameter parameters: 参数字典
    /// - parameter finished:   完成回调
   private func request(method: HMRequestMethod, URLString:String, parameters: [String:AnyObject]?,finished: HMRequestCallBack) {

    
        // 定义成功回调
        let success = {
            (task: NSURLSessionDataTask, result: AnyObject) -> Void in
            finished(result: result, error: nil)
    }
        
        // 定义失败回调
        let failure = {
            (task: NSURLSessionDataTask?, error: NSError) -> Void in
            print(error)
            finished(result: nil, error: error)
        }
        
        
        if method == HMRequestMethod.GET {
            GET(URLString, parameters: parameters, success: success, failure: failure)
        }
        
        if method == HMRequestMethod.POST {
            POST(URLString, parameters: parameters, success: success, failure: failure)
        }
        
        
    
    }
}
